iT邦幫忙

2023 iThome 鐵人賽

DAY 6
0
自我挑戰組

自己的 Leak, 自己抓(swift)系列 第 6

初入 SwiftSyntax

  • 分享至 

  • xImage
  •  

初入 SwiftSyntax

今天我們要引入第 2 個 library SwiftSyntax

並且會稍微帶過三個元件,分別是:

  • Parser
  • SyntaxVisitor
  • SourceLocationConverter

Package.swift

這邊 SwiftSyntax 的版本號比較特殊 508.0.0,對應到 swift 5.8

// swift-tools-version: 5.7
// The swift-tools-version declares the minimum version of Swift required to build this package.

import PackageDescription

let package = Package(
    name: "LeakDetect",

    dependencies: [
        .package(url: "https://github.com/jpsim/SourceKitten", from: "0.34.1"),

        .package(
            url: "https://github.com/apple/swift-syntax",
            from: "508.0.0"
        ),
    ],
    targets: [
        .target(
            name: "LeakDetectKit",
            dependencies: [
                .product(name: "SourceKittenFramework", package: "SourceKitten"),
                .product(name: "SwiftSyntax", package: "swift-syntax"),
                .product(name: "SwiftParser", package: "swift-syntax"),
            ]
        ),
    ]
)

SwiftParser(取得 AST)

Parser 將 source code 解析成 AST

import SwiftParser
import SwiftSyntax
import PathKit

let path = "My.swift"
let code = try Path(path).read()
let sourceFile = Parser.parse(source: code)

SyntaxVisitor

我們可以透過自定義 Visitor 去訪問特定的語法節點(Syntax Node)

final class MyVisitor: SyntaxVisitor {
  override final func visit(
    _ node: IdentifierExprSyntax
  ) -> SyntaxVisitorContinueKind {
    return .visitChildren
  }
}
let visitor = MyVisitor(viewMode: .sourceAccurate)
visitor.walk(sourceFile)

SourceLocationConverter

SourceLocationConverter 可以將 語法節點offset 轉換成 SourceLocation

let node: IdentifierExprSyntax = xxx

let converter = SourceLocationConverter(file: path, tree: sourceFile)
let location: SourceLocation = converter.location(
  for: node.positionAfterSkippingLeadingTrivia
)

SourceLocation

SourceLocation 可以取得兩項重要屬性分別是

  • line
  • column

在掃瞄完畢後,我們可透過這樣的格式 path:line:col 輸出位置,讓 VSCode 快速導引

/home/My.swift:10:20

/// Represents a source location in a Swift file.
public struct SourceLocation: Hashable, Codable, CustomDebugStringConvertible {

  /// Line and column that can be computed on demand.
  private var compLoc: ComputedLocation?

  /// The UTF-8 byte offset into the file where this location resides.
  public let offset: Int

  /// The line in the file where this location resides. 1-based.
  public var line: Int? {
    return compLoc?.line
  }

  /// The UTF-8 byte offset from the beginning of the line where this location
  /// resides. 1-based.
  public var column: Int? {
    return compLoc?.column
  }

  /// The file in which this location resides.
  public var file: String? {
    return compLoc?.file
  }
}

上一篇
SwiftSyntax 前導 (AST)
下一篇
深入 SyntaxVisitor
系列文
自己的 Leak, 自己抓(swift)30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言